package com.yanggeng.demo.beginnerguidedemo.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.yanggeng.demo.beginnerguidedemo.utils.DeviceParams;


/**
 * Created by yanggeng on 2017/8/11.
 */

public class ConsumeLineChartView extends View {

    private String[] dates = new String[5]; // = new String[5];
    private float[] costs = new float[5]; // = new float[5];
    private Context context;
    private float lineWidth = DeviceParams.dip2px(getContext(), 1.5f);
    private float circleRadius = DeviceParams.dip2px(getContext(), 4f); //圆圈外环半径
    private float solidCircleRadius = DeviceParams.dip2px(getContext(), 2.5f); //圆圈实心半径
    private int shadowColor = Color.parseColor("#32FFA82A");
    private int normalCircleColor = Color.parseColor("#4C2FAFFF"); //非当前月圆圈外环颜色
    private int currCircleColor = Color.parseColor("#FFA82A");
    private int lineColor = Color.parseColor("#FFA82A");
    private int currTextColor = Color.parseColor("#FFA82A");
    private int normalTextColor = Color.parseColor("#637C95");
    private int normalLineColor = Color.parseColor("#E1F0FF");
    private int costTextSize = DeviceParams.sp2px(getContext(), 18);
    private int monthTextSize = DeviceParams.sp2px(getContext(), 12);

    private float height; //整体高度
    private float width; //整体宽度
    private float maxValue; //消费最大值
    private float lineHeight; //折线图高度

    private float softLineWidth = DeviceParams.dip2px(getContext(), 5);

    private float cellHeight;
    private float cellWidth;

    private Paint costTextPaint;
    private Paint costLinePaint;
    private Paint circlePaint;
    private Paint monthTextPaint;
    private Paint shadowPaint;
    private Paint softLinePaint;

    private Path lastLinePath;
    private DashPathEffect pathEffect;
    private Path shadowPath;
    private boolean isHome = false;

    private boolean defaultFlag = true; //默认绘制标记，为true时 只绘制背景虚线、横坐标轴和月份

    public ConsumeLineChartView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        costLinePaint = new Paint();
        costLinePaint.setStrokeWidth(lineWidth);

        costTextPaint = new Paint();
        costTextPaint.setTextSize(costTextSize);
        costTextPaint.setARGB(255, 255, 255, 255);
        costTextPaint.setTextAlign(Paint.Align.CENTER);
//        costTextPaint.setTypeface(ICheApplication.numberTypeface);

        circlePaint = new Paint();
        circlePaint.setAntiAlias(true);
        circlePaint.setStrokeWidth(lineWidth);

        monthTextPaint = new Paint();
        monthTextPaint.setTextSize(DeviceParams.sp2px(getContext(), 12));
        monthTextPaint.setARGB(255, 255, 255, 255);
        monthTextPaint.setTextAlign(Paint.Align.CENTER);
        monthTextPaint.setColor(normalTextColor);
//        monthTextPaint.setTypeface(ICheApplication.numberTypeface);

        shadowPaint = new Paint();//Paint.ANTI_ALIAS_FLAG
        shadowPaint.setColor(shadowColor);
        shadowPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        pathEffect = new DashPathEffect(new float[]{softLineWidth, softLineWidth}, 1);

        softLinePaint = new Paint();
        softLinePaint.setStyle(Paint.Style.STROKE);
        softLinePaint.setStrokeWidth(lineWidth);
        softLinePaint.setAntiAlias(true);
        softLinePaint.setPathEffect(pathEffect);

        lastLinePath = new Path();
        shadowPath = new Path();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        height = MeasureSpec.getSize(heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);
        cellHeight = height / 4;
        cellWidth = width / 10;
        lineHeight = cellHeight * 2;
        setMeasuredDimension((int) width, (int) height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        canvas.clipRect(0, 0, width, height);
        Paint paint = new Paint();
        paint.setColor(Color.WHITE);
        canvas.drawRect(0, 0, width, height, paint);
//        setLayerType(LAYER_TYPE_SOFTWARE, null); //使用DashPathEffect绘制虚线不支持硬件加速
        drawLine(canvas);
        drawMonthText(canvas);
    }

    private void drawLine(Canvas canvas) {

        // 画背景横坐标轴
        costLinePaint.setColor(normalLineColor);
        canvas.drawLine(0, cellHeight * 3, width, cellHeight * 3, costLinePaint);

        //画背景两条虚线
        softLinePaint.setColor(normalLineColor);
        lastLinePath.reset();
        lastLinePath.moveTo(0, cellHeight);
        lastLinePath.lineTo(width, cellHeight);
        canvas.drawPath(lastLinePath, softLinePaint);
        lastLinePath.reset();
        lastLinePath.moveTo(0, cellHeight * 2);
        lastLinePath.lineTo(width, cellHeight * 2);
        canvas.drawPath(lastLinePath, softLinePaint);
//        canvas.drawLine(0, cellHeight, width, cellHeight, softLinePaint);
//        canvas.drawLine(0, cellHeight * 2, width, cellHeight * 2, softLinePaint);

        if (!defaultFlag) {
            maxValue = getMax(costs);
            costLinePaint.setColor(lineColor);
            shadowPath.reset();
            shadowPath.moveTo(0, cellHeight * 3);
            canvas.drawLine(0, cellHeight * 3 - lineWidth, cellWidth, cellHeight + (1 - costs[0] / maxValue) * lineHeight, shadowPaint); //填充
            canvas.drawLine(0, cellHeight * 3, cellWidth, cellHeight + (1 - costs[0] / maxValue) * lineHeight, costLinePaint);
            shadowPath.lineTo(cellWidth, cellHeight + (1 - costs[0] / maxValue) * lineHeight);
            for (int i = 0; i < costs.length; i++) {
                float y = cellHeight + (1 - costs[i] / maxValue) * lineHeight;

                //画线
                if (i < costs.length - 1) {
                    float y2 = cellHeight + (1 - costs[i + 1] / maxValue) * lineHeight;
                    if ((DateUtils.getYear() + "-" + DateUtils.getMonth()).equals(dates[i])) {
//                    canvas.translate(cellWidth * (i * 2 + 1), y);
                        lastLinePath.reset();
                        lastLinePath.moveTo(cellWidth * (i * 2 + 1), y);
                        lastLinePath.lineTo(cellWidth * ((i + 1) * 2 + 1), y2);
                        // PathEffect是用来控制绘制轮廓(线条)的方式
                        // 代码中的float数组,必须是偶数长度,且>=2,指定了多少长度的实线之后再画多少长度的空白.
                        // 如本代码中,绘制长度5的实线,再绘制长度5的空白,再绘制长度5的实线,再绘制长度5的空白,依次重复.1是偏移量,可以不用理会.
                        softLinePaint.setColor(lineColor);
                        canvas.drawPath(lastLinePath, softLinePaint);
                        softLinePaint.setColor(lineColor);
                        canvas.drawLine(cellWidth * (i * 2 + 1), y, cellWidth * ((i + 1) * 2 + 1), y2, shadowPaint); //填充
//                        canvas.drawLine(cellWidth * (i * 2 + 1), y, cellWidth * ((i + 1) * 2 + 1), y2, softLinePaint); //绘制虚线
                    } else {
                        canvas.drawLine(cellWidth * (i * 2 + 1), y, cellWidth * ((i + 1) * 2 + 1), y2, shadowPaint); //填充

                        canvas.drawLine(cellWidth * (i * 2 + 1), y, cellWidth * ((i + 1) * 2 + 1), y2, costLinePaint); //绘制实线
                    }
                    shadowPath.lineTo(cellWidth * ((i + 1) * 2 + 1), y2);
                }
                if (i == costs.length - 1) {
                    canvas.drawLine(cellWidth * (i * 2 + 1), y - lineWidth, 0, cellHeight * 3 - lineWidth, shadowPaint); //填充
                    canvas.drawLine(cellWidth * (i * 2 + 1), y, width, cellHeight * 3, costLinePaint); //绘制最后一个点到屏幕最后边的线
                    shadowPath.lineTo(width, cellHeight * 3);
                    shadowPath.close();
                }

                //画圆圈
                if (i == costs.length - 2) {
                    circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
                    circlePaint.setColor(currCircleColor);
                    costTextPaint.setColor(currTextColor);
                    canvas.drawCircle(cellWidth * (i * 2 + 1), y, circleRadius, circlePaint); //画当前月份圆圈
                } else {
                    circlePaint.setStyle(Paint.Style.STROKE);
                    circlePaint.setColor(normalCircleColor);
                    costTextPaint.setColor(normalTextColor);
                    canvas.drawCircle(cellWidth * (i * 2 + 1), y, circleRadius, circlePaint); //画其他圆圈外环
                }

                canvas.drawText(costs[i] + "", cellWidth * (i * 2 + 1), y - 20, costTextPaint); //绘制坐标点值（消费金额）

                circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
                circlePaint.setColor(Color.WHITE);
                if (i != costs.length - 2) {
                    canvas.drawCircle(cellWidth * (i * 2 + 1), y, solidCircleRadius, circlePaint); //画其他圆圈实心
                }
            }
            if (!isHome) {
                shadowPath.setFillType(Path.FillType.EVEN_ODD);
                canvas.drawPath(shadowPath, shadowPaint); //绘制阴影
            }
        } else {
            for (int i = 0; i < costs.length; i++) {
                circlePaint.setStyle(Paint.Style.STROKE);
                circlePaint.setColor(normalCircleColor);
                canvas.drawCircle(cellWidth * (i * 2 + 1), cellHeight * 3, circleRadius, circlePaint); //画圆圈外环
                circlePaint.setStyle(Paint.Style.FILL);
                circlePaint.setColor(Color.WHITE);
                canvas.drawCircle(cellWidth * (i * 2 + 1), cellHeight * 3, solidCircleRadius, circlePaint); //画圆圈实心
            }
        }
    }


    private void drawMonthText(Canvas canvas) {
        for (int i = 0; i < dates.length; i++) {
            canvas.drawText(dates[i], cellWidth * (i * 2 + 1), cellHeight * 3 + 70, monthTextPaint);
        }
    }

    private float getMax(float[] data) {
        float max = data[0];
        for (int i = 1; i < data.length; i++) {
            if (data[i] > max) {
                max = data[i];
            }
        }
        return max;
    }

    public void setInfo(String[] month, float[] costs, boolean isHome) {
        this.dates = month;
        this.costs = costs;
        defaultFlag = true;
        this.isHome = isHome;
        for (int i = 0; i < costs.length; i++) {
            if (costs[i] != 0f) {
                defaultFlag = false;
                break;
            }
        }
        invalidate();
    }
}
